package cn.uai.activiti8.approval.service.impl;

import cn.uai.activiti8.approval.service.ProductManageParallelProcessService;
import cn.uai.activiti8.cache.GlobalCache;
import cn.uai.activiti8.dto.Result;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

import static cn.uai.activiti8.enums.RespCodeEnum.TASK_NOT_FOUND;
import static cn.uai.activiti8.enums.RoleEnum.ROLE_PURCHASER;

/**
 * @desc 商品并行审批管理流程
 * @author uai
 * @since 2025/8/10 21:34
 * @version 1.0
 */
@Service
public class ProductManageParallelProcessServiceImpl extends InfrastructureServiceImpl implements ProductManageParallelProcessService {

    private static final String PROCESS_DEFINITION_ID = "multi-product-manage-k:1:805003";
    private static final String PROCESS_DEFINITION_KEY = "multi-product-manage-k";

    /**
     * 启动流程
     * @param body
     * @return
     */
    @Override
    public ProcessInstance start(String body) {
        JSONObject bodyJson = JSON.parseObject(body);
        Map<String, Object> variables = new HashMap<>();
        Long uid = bodyJson.getLong("uid");
        Long rid = userService.findRidByUid(uid);
        dynamicAssignStartVariables(rid, variables);
        return super.start(PROCESS_DEFINITION_ID, variables);
    }

    @Override
    public String complete(String body) {
        Map<String, Object> variable = new HashMap<>();
        JSONObject bodyJson = JSONObject.parseObject(body);
        String taskId = bodyJson.getString("taskId");
        String processInstanceId = bodyJson.getString("processInstanceId");
        Integer actionType = bodyJson.getInteger("actionType");
        Long uid = bodyJson.getLong("uid");
        Long rid = userService.findRidByUid(uid);
        variable.put("actionType", actionType);
        boolean isPass = false;
        switch (actionType) {
            case 1 -> isPass = true;
            case 2, 3 -> isPass = false;
        }
        variable.put("isPass", isPass);
        dynamicAssignCompleteVariables(rid, variable);
        bindingParallelVariables(processInstanceId, rid, variable, isPass);
        try {
            taskService.complete(taskId, variable);
        } catch (ActivitiObjectNotFoundException e) {
            return Result.exception(TASK_NOT_FOUND.getCode(), "任务 taskId [" + taskId + "] 已完成，或输入的taskId不存在");
        }
        return taskId;
    }

    @Override
    protected void dynamicAssignStartVariables(Object original, Map<String, Object> variables) {
        // 普通店员 给下一级设置变量
        variables.put("storeAssistants", "690028525338693");
    }

    @Override
    protected void dynamicAssignCompleteVariables(Object original, Map<String, Object> variables) {
        Long rid = (Long) original;
        if (ROLE_PURCHASER.getRid().equals(rid)) {
            // 采购员 给下一级设置变量
            variables.put("storeManager", "681374462742597");
            variables.put("warehouseSupervisor", "700661117624389");
            variables.put("assistantRegionalManager", "682799093862469");
        } else if (GlobalCache.PARALLEL_APPROVAL_ROLE.contains(rid)) {
            // 部门主管（店长）、仓管员、经理助理 给下一级设置变量
            variables.put("regionalManager", "681372686954565");
        }
    }

    /**
     * 绑定并行审批变量
     * @param rid 角色id
     * @param variables 变量
     * @param isPass 是否通过，[true: 通过, false: 不通过]
     */
    private void bindingParallelVariables(String processInstanceId, Long rid, Map<String, Object> variables, Boolean isPass) {
        if (GlobalCache.PARALLEL_APPROVAL_ROLE.contains(rid)) {
            Map<String, Object> map = GlobalCache.PARALLEL_APPROVAL_COUNT.getOrDefault(processInstanceId, new HashMap<>());
            Integer parallelApprovalCount = (Integer) map.getOrDefault("parallelApprovalCount", 0);
            parallelApprovalCount++;
            map.put("parallel_pass_" + parallelApprovalCount, isPass);
            map.put("parallelApprovalCount", parallelApprovalCount);
            GlobalCache.PARALLEL_APPROVAL_COUNT.put(processInstanceId, map);
        } else {
            variables.put("isPass", isPass);
        }
    }
}
